#pragma once
#include <iostream>
#include "socket.hpp"
#include <fstream>
#include<functional>
#include "TcpServer.hpp"
#include "HttpProtocol.hpp"



//如果动态界面，会传入一个函数，在该函数中进行进程替换，执行任务
//using func_t=std::function<std::shared_ptr<HttpRequest>(std::shared_ptr<HttpResponse> hs)>; 
class HttpService
{
public:
    HttpService()
    {
        _mime_type.insert(std::make_pair(".html", "text/html"));
        _mime_type.insert(std::make_pair(".css", "text/css"));
        _mime_type.insert(std::make_pair(".js", "application/x-javascript"));
        _mime_type.insert(std::make_pair(".png", "image/png"));
        _mime_type.insert(std::make_pair(".jpg", "image/jpeg"));
        _mime_type.insert(std::make_pair(".unknown", "text/html"));

        _code_to_desc.insert(std::make_pair(100, "Continue"));
        _code_to_desc.insert(std::make_pair(200, "OK"));
        _code_to_desc.insert(std::make_pair(301, "Moved Permanently"));
        _code_to_desc.insert(std::make_pair(302, "Found"));
        _code_to_desc.insert(std::make_pair(404, "Not Found"));
        _code_to_desc.insert(std::make_pair(500, "Internal Server Error"));
    }
    // 二进制方式打开
    std::string ReadFileBinary(const std::string &path, int *size)
    {
        std::ifstream in(path, std::ios::binary);
        if (!in.is_open())
        {
            return std::string();
        }
        // 获取字节数
        in.seekg(0, in.end);
        int filesize = in.tellg();
        in.seekg(0, in.beg);
        // 读取
        std::string content;
        content.resize(filesize);
        in.read((char *)content.c_str(), filesize);
        in.close();
        *size = filesize;
        return content;
    }
    std::string HttpHanderService(std::string req)
    {
        // 获取请求报文
        auto request = Factory().BuildHttpRequest();
        request->Dresialize(req);
        request->Print();

        auto res = Factory().BuildHttpResponse();
        // 获取路径
        std::string path = request->path();
        // 如果需要重定向
        if (path == "Wroot/redir")
        {
            std::string newurl = "https://www.baidu.com";
            res->AddStatusLine(301, _code_to_desc[301]);
            res->AddHeader("Location", newurl);
        }
        else
        {
            int size = 0;
            std::string text = ReadFileBinary(path, &size);
            if (text.empty())
            {
                res->AddStatusLine(404, _code_to_desc[404]);
                std::string text404 = ReadFileBinary(file404, &size);
                res->AddHeader("Content_type", _mime_type[".html"]);
                res->AddHeader("Content-Length", std::to_string(size));
                res->AddRespBody(text404);
            }
            else
            {
                res->AddRespBody(text);
                res->AddStatusLine(200, _code_to_desc[200]);
                std::string suffix = request->suffix();
                res->AddHeader("Content_type", _mime_type[suffix]);
                res->AddHeader("Content-Length", std::to_string(size));
            }
        }
        std::string response = res->Resialize();
        //std::cout << response << std::endl;
        return response;
    }
    ~HttpService() {}

private:
    std::unordered_map<int, std::string> _code_to_desc;
    std::unordered_map<std::string, std::string> _mime_type;
    //std::unordered_map<std::string, func_t> _func_type;
    
};
